mod ffmpeg;
use core_api::{db, is_process_alive};
use ffmpeg::FfmpegController;

use std::{env, path::Path, sync::Mutex};

use lazy_static::lazy_static;

pub fn get_args() -> Vec<String> {
    // 获取命令行参数（包括程序名）
    let args: Vec<String> = env::args().skip(1).collect();
    log::info!("args: {:?}", &args);
    args
}

// 全局消息管理器
lazy_static! {
    static ref GMM: Mutex<Option<db::MessageManager>> = Mutex::new(None);
}
/// 发送消息
fn send_msg(message: db::Message) -> Result<(), String> {
    GMM.lock().unwrap().as_ref().unwrap().send_msg(message)
}

///初始化 全局消息管理器 GMM
pub fn init_gmm() {
    let mut mm = db::MessageManager::new();
    mm.init(false);
    *GMM.lock().unwrap() = Some(mm);
}

pub fn start_recording(
    output_file: &Path,
    watermark_text: String,
    force_open_camera: bool,
    t: u64,
    bwexam_pid: u32,
) -> Result<u32, String> {
    let pid = std::process::id();

    let outfile = output_file.to_str().unwrap();

    let mut fc = FfmpegController::new();
    let log_rx = fc.run_async(outfile.to_string(), watermark_text, force_open_camera);
    let log_thread = std::thread::spawn(move || {
        const TIME: &str = "@T:";
        for line_str in log_rx {
            let line = line_str.as_str();
            // eprintln!("recoreder===>{}", line);//1
            match line {
                "@E:start" => {
                    let _ = send_msg(db::Message::new(
                        db::MsgFlag::RECORDING,
                        db::MsgStatus::START,
                        format!("{}", pid),
                        String::default(),
                    ));
                }
                "@E:stop" => {}

                _ if line.starts_with(TIME) => {
                    let pts_str = &line[TIME.len()..];
                    //println!("pts_str=>{} ", pts_str);
                    let pts = pts_str.trim().parse::<u64>().unwrap_or(0);
                    let seconds = pts as f64 / 1000.0;
                    let h = (seconds / 3600.0) as i32;
                    let m = ((seconds - (h as f64 * 3600.0)) / 60.0) as i32;
                    let s = seconds as i32 % 60;
                    //let ms = ((seconds - (seconds as i32) as f64) * 100.0) as i32;

                    // let time_str = format!("{:02}:{:02}:{:02}:{:02}", h, m, s, ms);
                    let time_str = format!("{:02}:{:02}:{:02}", h, m, s);
                    //println!("time={}", time_str);
                    let _ = send_msg(db::Message::new(
                        db::MsgFlag::RECORDING,
                        db::MsgStatus::PROGRESS,
                        format!("{}", pid),
                        time_str.to_string(),
                    ));
                }
                _ => {
                    // 错误或调试信息
                    //if line.starts_with("!!:") {
                    log::info!("[common]{}", line);
                    //}
                }
            }
        }
    });

    let pid_file_str = format!("logs/{}.pid", pid);
    let pid_path = std::path::PathBuf::from(&pid_file_str);
    // 创建pid 文件,说明进程正在运行
    let _ = std::fs::File::create(pid_path.as_path());

    let stop_thread = std::thread::spawn(move || {
        if t > 0 {
            //用于测试等待多长退出
            std::thread::sleep(std::time::Duration::from_secs(t));
        } else {
            while pid_path.exists() && is_process_alive(bwexam_pid) {
                // 如果pid文件存在,且主进程存在
                //log::info!("=====ff7scre {} is running: {:?},bwexam_pid={}", pid, &pid_path,bwexam_pid);
                std::thread::sleep(std::time::Duration::from_secs(3));
            }
        }

        let ret = fc.wait_stop();
        ret
    });

    let ret = stop_thread.join().unwrap_or(0);
    log::info!(
        "start_recording_1_3 stop_thread end,pid={},ret ={}",
        pid,
        ret
    );

    // 等待日志线程退出
    let _ = log_thread.join();
    log::info!("start_recording_2_3 log_thread end,pid={}", pid);

    let _ = send_msg(db::Message::new(
        db::MsgFlag::RECORDING,
        db::MsgStatus::SUCCESS,
        format!("{}", pid),
        format!("pid:{} ret  {}", pid, ret),
    ));

    log::info!("start_recording_3_3 all end ,pid={},ret ={}", pid, ret);
    //无论如何删除文件
    let _ = std::fs::remove_file(std::path::PathBuf::from(&pid_file_str));

    Ok(pid)
}
